package Hxw3DEngine.core.materials.shader.filters {
	
	import Hxw3DEngine.core.materials.shader.utils.FcRegisterLabel;
	import Hxw3DEngine.core.materials.shader.utils.ShaderRegisterCache;
	import Hxw3DEngine.core.materials.shader.utils.ShaderRegisterElement;
	import Hxw3DEngine.core.materials.shader.utils.VcRegisterLabel;
	import Hxw3DEngine.utils.Color;
	import Hxw3DEngine.proxy.Stage3DProxy;
	import Hxw3DEngine.core.Resource.geometry.ResourceGeometry;
	
	/**
	 * fog filter 
	 * @author Neil
	 * 
	 */	
	public class FogFilter extends Filter3D {
		
		private var eyeVary 	: ShaderRegisterElement;
		private var _fogConst 	: ShaderRegisterElement;
		private var _fogData 	: Vector.<Number>;
		private var _eyePosData	: Vector.<Number>;
		private var _fogDistance: Number = 1;
		private var _fogColor 	: Color;
		
		/**
		 *  
		 * @param fogDistance	雾气距离
		 * @param color			雾颜色
		 * 
		 */		
		public function FogFilter(fogDistance : Number, color : Color) {
			super("FogFilter");
			this._fogDistance 	= fogDistance;
			this._fogData 	  	= Vector.<Number>([0, 0, 0, 0]);
			this._eyePosData	= Vector.<Number>([0, 0, 0, 0]);
			this.fogColor 		= color;
		}
		
		/**
		 * 设置fog距离 
		 * @param value
		 * 
		 */		
		public function set fogDistance(value : Number) : void {
			if (value <= 0) {
				value = 1;
			}
			this._fogDistance = value;
			this._fogData[3]  = 1 / value;
		}
		
		public function get fogDistance() : Number {
			return _fogDistance;
		}
		
		/**
		 * 雾颜色 
		 * @param value
		 * 
		 */		
		public function set fogColor(value : Color) : void {
			this._fogColor = value;
			this._fogData[0] = value.r;
			this._fogData[1] = value.g;
			this._fogData[2] = value.b;
			this._fogData[3] = 1 / fogDistance;
		}
		
		public function get fogColor() : Color {
			return _fogColor;
		}
		
		override public function update():void {
			this._eyePosData[0] = Stage3DProxy.cameraPos.x;
			this._eyePosData[1] = Stage3DProxy.cameraPos.y;
			this._eyePosData[2] = Stage3DProxy.cameraPos.z;
		}
		
		override public function getFragmentCode(regCache:ShaderRegisterCache):String {
			super.getFragmentCode(regCache);
			this.eyeVary = regCache.getFreeV("雾申请的空闲的V");
			
			var fogFc : ShaderRegisterElement = regCache.getFc(1, new FcRegisterLabel(_fogData),"雾的颜色");
			var ft0   : ShaderRegisterElement = regCache.getFt("雾申请的空闲的ft");
			
			dp3(ft0.w,eyeVary.xyz,eyeVary.xyz);
			// 顶点距离相机距离
			sqt(ft0.w,ft0.w);
			// 距离除以distance
			mul(ft0.w,ft0.w,fogFc.w);
			// -1
			sub(ft0.w,ft0.w,regCache.fc0123.y);
			// max 0 or dis
			max(ft0.w,regCache.fc0123.x,ft0.w);
			neg(ft0.w,ft0.w);
			exp(ft0.w, ft0.w);
			sub(ft0.xyz, regCache.oc.xyz, fogFc.xyz);
			mul(ft0.xyz, ft0.xyz, ft0.w);
			add(regCache.oc.xyz,fogFc.xyz,ft0.xyz);
			
			regCache.removeFt(ft0);
			return code;
		}
		
		override public function getVertexCode(regCache:ShaderRegisterCache):String {
			super.getVertexCode(regCache);
			var eyeVc : ShaderRegisterElement = regCache.getVc(1, new VcRegisterLabel(_eyePosData),"相机的坐标值");
			var vt0 : ShaderRegisterElement = regCache.getVt("雾申请的空闲VT");
			
			m44(vt0,regCache.getVa(ResourceGeometry.POSITION),regCache.vcWorld);
			sub(eyeVary,vt0,eyeVc);
			
			regCache.removeVt(vt0);
			return code;
		}
				
	}
}
